/* **********************************************************************************
 *
 * Copyright (c) TMF.AscendedThemeKit.Unthemed.NET Project. All rights reserved.
 *
 * This source code is subject to terms and conditions of the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed. A copy of the license can be found in the License.html file
 * at the root of this distribution. If you can not locate the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed, please send an email to ascendlic@<TBD>.
 * By using this source code in any fashion, you are agreeing to be bound by
 * the terms of the Shared Source License for TMF.AscendedThemeKit.Unthemed.NET.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * **********************************************************************************/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace TMF.AscendedThemeKit.Unthemed.Windows.Forms
{
    /// <summary>
    /// Renders the gradient caption based on the properties.
    /// </summary>
    public class GradientCaptionRender : GradientBackgroundRender
    {
        private SolidBrush _foreBrush;
        private Image _image;
        private ContentAlignment _imageAlign;
        private ContentAlignment _textAlign;
        private int _posOffset = 2;
        private StringFormat _textFormat = new StringFormat();
        private string _text = string.Empty;
        private Font _font;
        private Color _foreColor;
        private bool _disposed;
        private bool _useCompatibleTextRendering;
        private float _internalBottom;
        private float _internalLeft;
        private float _internalRight;
        private float _internalTop;
        private bool _rightToLeft;
        private bool _isImageFromImageList;
        private bool _hidePrefix;
        private int _autoSizeBuffer = 3;

        /// <summary>
        /// Occurs when the ForeColor property changes.
        /// </summary>
        public event EventHandler ForeColorChanged;

        /// <summary>
        /// Occurs when the ImageAlign property changes.
        /// </summary>
        public event EventHandler ImageAlignChanged;

        /// <summary>
        /// Occurs when the Image property changes. 
        /// </summary>
        public event EventHandler ImageChanged;

        /// <summary>
        /// Occurs when the TextAlign property changes. 
        /// </summary>
        public event EventHandler TextAlignChanged;

        /// <summary>
        /// Occurs when the Image property changes. 
        /// </summary>
        public event EventHandler TextChanged;

        /// <summary>
        /// Initializes a new instance of the GradientCaptionRender class.
        /// </summary>
        public GradientCaptionRender() : base()
        {
            this._textFormat.FormatFlags = StringFormatFlags.NoWrap;
            this._textFormat.LineAlignment = StringAlignment.Center;
            this._textFormat.Trimming = StringTrimming.EllipsisCharacter;

            base.GradientHighColor = SystemColors.GradientActiveCaption;
            base.GradientLowColor = SystemColors.ActiveCaption;
            base.GradientMode = LinearGradientMode.Vertical;

            base.Border = new Border(1);

            this._imageAlign = ContentAlignment.MiddleRight;
            this._foreColor = SystemColors.ActiveCaptionText;
            this._foreBrush = new SolidBrush(this._foreColor);
            this._font = new Font("Tahoma", 10.0f);
            this._textAlign = ContentAlignment.MiddleLeft;

        }

        /// <summary>
        /// Gets or sets a value indication whether to hide prefix in text.
        /// </summary>
        public bool HidePrefix
        {
            get { return _hidePrefix; }
            set { _hidePrefix = value; }
        }

        /// <summary>
        /// The color assoicated with the text.
        /// </summary>
        public Color ForeColor
        {
            get
            {
                return this._foreColor;

            }

            set
            {
                if (value == this._foreColor)
                {
                    return;

                }

                this._foreColor = value;
                this.CreateForeBrush();

                this.OnForeColorChanged(new EventArgs());

            }

        }

        /// <summary>
        /// The image associated with this control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Drawing.Image . The image associated with this control.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public Image Image
        {
            get
            {
                return this._image;
            }

            set
            {
                if (this._image != value)
                {
                    this._image = value;

                    this.OnImageChanged(new EventArgs());

                }

            }

        }

        /// <summary>
        /// The ContentAlignment associated with this controls image.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Drawing.ContentAlignment . The ContentAlignment associated with this controls image.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public ContentAlignment ImageAlign
        {
            get
            {
                return this._imageAlign;

            }

            set
            {
                if (value == this._imageAlign)
                {
                    return;

                }

                this._imageAlign = value;

                this.OnImageAlignChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the bottom positon of internal rendering.
        /// </summary>
        protected float InternalBottom
        {
            get
            {
                return this._internalBottom;

            }

            set
            {
                this._internalBottom = value;

            }

        }

        /// <summary>
        /// Gets or sets the left positon of internal rendering.
        /// </summary>
        protected float InternalLeft
        {
            get
            {
                return this._internalLeft;

            }

            set
            {
                this._internalLeft = value;

            }

        }

        /// <summary>
        /// Gets or sets the right positon of internal rendering.
        /// </summary>
        protected float InternalRight
        {
            get
            {
                return this._internalRight;

            }

            set
            {
                this._internalRight = value;

            }

        }

        /// <summary>
        /// Gets or sets the top positon of internal rendering.
        /// </summary>
        protected float InternalTop
        {
            get
            {
                return this._internalTop;

            }

            set
            {
                this._internalTop = value;

            }

        }

        /// <summary>
        /// gets or sets if the image is from an image list
        /// </summary>
        public bool IsImageFromImageList
        {
            get
            {
                return this._isImageFromImageList;

            }

            set
            {
                this._isImageFromImageList = value;

            }

        }

        /// <summary>
        /// Gets or sets if the render is right to left.
        /// </summary>
        public bool RightToLeft
        {
            get 
            { 
                return this._rightToLeft;
            
            }

            set 
            { 
                this._rightToLeft = value;
            
            }

        }

        /// <summary>
        /// Gets or sets the text associated with this control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.String . The text associated with this control.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public string Text
        {
            get
            {
                return this._text;

            }

            set
            {
                if (value == this._text)
                {
                    return;

                }

                this._text = value;

            }

        }

        /// <summary>
        /// The ContentAlignment associated with this controls text.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Drawing.ContentAlignment . The ContentAlignment associated with this controls text.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public ContentAlignment TextAlign
        {
            get
            {
                return this._textAlign;

            }

            set
            {
                if (value == this._textAlign)
                {
                    return;

                }

                this._textAlign = value;

                this.OnTextAlignChanged(new EventArgs());

            }

        }

        /// <summary>
        /// Gets or sets the font associated with this control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Drawing.Font . The font associated with this control.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public Font Font
        {
            get
            {
                return this._font;

            }

            set
            {
                if (value == this._font)
                {
                    return;

                }

                this._font = value;

            }

        }

        /// <summary>
        /// Gets or sets a value that determines whether to use the compatible text rendering engine (GDI+) or not (GDI). 
        /// </summary>
        /// <value>
        /// true if the compatible text rendering engine (GDI+) is used; otherwise, false. 
        /// </value>
        public bool UseCompatibleTextRendering
        {
            get
            {
                return this._useCompatibleTextRendering;

            }

            set
            {
                this._useCompatibleTextRendering = value;

            }

        }

        /// <summary>
        /// Creates the solid brush needed to draw the foreground.
        /// </summary>
        protected virtual void CreateForeBrush()
        {
            if (base.Enabled)
            {
                Color adjustedForeColor = Color.FromArgb(base.Alpha, this._foreColor);

                this._foreBrush = new SolidBrush(adjustedForeColor);

            }
            else
            {
                Color adjustedGrayedForeColor = Color.FromArgb(base.Alpha, SystemColors.GrayText);

                this._foreBrush = new SolidBrush(adjustedGrayedForeColor);

            }

        }

        /// <summary>
        /// Draws the text and/or the image of the control.
        /// </summary>
        /// <param name="e">A System.Windows.Forms.PaintEventArgs that contains the event data.</param>
        public override void Render(System.Windows.Forms.PaintEventArgs e)
        {
            if (e == null)
            {
                throw new ArgumentNullException("e");

            }

            RectangleF bounds;

            ContentAlignment adjustedTextAlignment = this.GetAdjustedTextAlignment();

            this.InternalTop = (this._posOffset + base.Padding.Top + this.Border.Top);
            this.InternalLeft = (this.DisplayRectangle.Left + base.Padding.Left + this._posOffset);
            float topPosition = (this.DisplayRectangle.Top + this._posOffset + base.Padding.Top + this.Border.Top);
            this.InternalRight = (this._posOffset + base.Padding.Right + this.Border.Right);
            this.InternalBottom = (this._posOffset + base.Padding.Bottom + this.Border.Bottom);

            if (this.DisplayRectangle.Height > 0 && this.DisplayRectangle.Width > 0)
            {
                base.Render(e);

                this.CreateForeBrush();
                
                ColorMatrix colorMatrix = new ColorMatrix();
                colorMatrix.Matrix33 = (this.Alpha / 255.0f); //33 is alpha

                ImageAttributes imageAttributes = new ImageAttributes();
                try
                {
                    imageAttributes.SetColorMatrix(colorMatrix);

                    if ((this._image != null) && (this._image.PixelFormat != System.Drawing.Imaging.PixelFormat.Undefined) && (this._image.Height > 0))
                    {
                        if (this._imageAlign == ContentAlignment.MiddleLeft)
                        {
                            Rectangle imageRectangle = new Rectangle((int)this.InternalLeft, (this.DisplayRectangle.Top + ((this.DisplayRectangle.Height / 2) - (this._image.Height / 2))), this._image.Width, this._image.Height);

                            if (base.Enabled)
                            {
                                if (this.Alpha != 255)
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel, imageAttributes);

                                }
                                else
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel);

                                }

                            }
                            else
                            {
                                ControlPaint.DrawImageDisabled(e.Graphics, this._image, (int)this.InternalLeft, (int)(this.DisplayRectangle.Top + ((this.DisplayRectangle.Height / 2.0f) - (this.Image.Height / 2.0f))), Color.Transparent);

                            }

                            if ((adjustedTextAlignment == ContentAlignment.TopLeft) || (adjustedTextAlignment == ContentAlignment.MiddleLeft) || (adjustedTextAlignment == ContentAlignment.BottomLeft))
                            {
                                this.InternalLeft += (this._posOffset + this.Image.Width);

                            }

                            bounds = new RectangleF(this.InternalLeft, topPosition, (this.DisplayRectangle.Width - ((this.InternalLeft - this.DisplayRectangle.Left) + this.InternalRight)), (this.DisplayRectangle.Height - (this.InternalTop + this.InternalBottom)));

                        }
                        else if (this._imageAlign == ContentAlignment.TopLeft)
                        {
                            Rectangle imageRectangle = new Rectangle((int)this.InternalLeft, (int)topPosition, this._image.Width, this._image.Height);

                            if (base.Enabled)
                            {
                                if (this.Alpha != 255)
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel, imageAttributes);

                                }
                                else
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel);

                                }

                            }
                            else
                            {
                                ControlPaint.DrawImageDisabled(e.Graphics, this._image, (int)this.InternalLeft, (int)topPosition, Color.Transparent);

                            }

                            if ((adjustedTextAlignment == ContentAlignment.TopLeft) || (adjustedTextAlignment == ContentAlignment.MiddleLeft) || (adjustedTextAlignment == ContentAlignment.BottomLeft))
                            {
                                this.InternalLeft += (this._posOffset + this.Image.Width);

                            }

                            bounds = new RectangleF(this.InternalLeft, topPosition, (this.DisplayRectangle.Width - ((this.InternalLeft - this.DisplayRectangle.Left) + this.InternalRight)), (this.DisplayRectangle.Height - (this.InternalTop + this.InternalBottom)));

                        }
                        else if (this._imageAlign == ContentAlignment.BottomLeft)
                        {
                            Rectangle imageRectangle = new Rectangle((int)this.InternalLeft, (int)(this.DisplayRectangle.Height - (this.InternalBottom + this._image.Height)), this._image.Width, this._image.Height);

                            if (base.Enabled)
                            {
                                if (this.Alpha != 255)
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel, imageAttributes);

                                }
                                else
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel);

                                }

                            }
                            else
                            {
                                ControlPaint.DrawImageDisabled(e.Graphics, this._image, (int)this.InternalLeft, (int)(this.DisplayRectangle.Height - (this.InternalBottom + this._image.Height)), Color.Transparent);

                            }

                            if ((adjustedTextAlignment == ContentAlignment.TopLeft) || (adjustedTextAlignment == ContentAlignment.MiddleLeft) || (adjustedTextAlignment == ContentAlignment.BottomLeft))
                            {
                                this.InternalLeft += (this._posOffset + this.Image.Width);

                            }

                            bounds = new RectangleF(this.InternalLeft, topPosition, (this.DisplayRectangle.Width - ((this.InternalLeft - this.DisplayRectangle.Left) + this.InternalRight)), (this.DisplayRectangle.Height - (this.InternalTop + this.InternalBottom)));

                        }
                        else if (this._imageAlign == ContentAlignment.MiddleRight)
                        {
                            Rectangle imageRectangle = new Rectangle((int)(this.DisplayRectangle.Right - this._posOffset - base.Padding.Right - this._image.Width), (int)(this.DisplayRectangle.Top + (this.DisplayRectangle.Height / 2.0f) - (this._image.Height / 2.0f)), this._image.Width, this._image.Height);

                            if (base.Enabled)
                            {
                                if (this.Alpha != 255)
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel, imageAttributes);

                                }
                                else
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel);

                                }

                            }
                            else
                            {
                                ControlPaint.DrawImageDisabled(e.Graphics, this._image, (int)(this.DisplayRectangle.Right - this._posOffset - base.Padding.Right - this._image.Width), (int)(this.DisplayRectangle.Top + (this.DisplayRectangle.Height / 2.0f) - (this._image.Height / 2.0f)), Color.Transparent);

                            }

                            this.InternalRight += (this._posOffset + this.Image.Width);

                            bounds = new RectangleF(this.InternalLeft, topPosition, (this.DisplayRectangle.Width - ((this.InternalLeft - this.DisplayRectangle.Left) + this.InternalRight)), (this.DisplayRectangle.Height - (this.InternalTop + this.InternalBottom)));

                        }
                        else if (this._imageAlign == ContentAlignment.TopRight)
                        {
                            Rectangle imageRectangle = new Rectangle((int)(this.DisplayRectangle.Right - this._posOffset - this._image.Width - base.Padding.Right), (int)(this.DisplayRectangle.Top + this._posOffset + base.Padding.Top), this._image.Width, this._image.Height);

                            if (base.Enabled)
                            {
                                if (this.Alpha != 255)
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel, imageAttributes);

                                }
                                else
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel);

                                }

                            }
                            else
                            {
                                ControlPaint.DrawImageDisabled(e.Graphics, this._image, (int)(this.DisplayRectangle.Right - this._posOffset - this._image.Width - base.Padding.Right), (int)(this.DisplayRectangle.Top + this._posOffset + base.Padding.Top), Color.Transparent);

                            }

                            this.InternalRight += (this._posOffset + this.Image.Width);

                            bounds = new RectangleF(this.InternalLeft, topPosition, (this.DisplayRectangle.Width - ((this.InternalLeft - this.DisplayRectangle.Left) + this.InternalRight)), (this.DisplayRectangle.Height - (this.InternalTop + this.InternalBottom)));

                        }
                        else if (this._imageAlign == ContentAlignment.BottomRight)
                        {
                            Rectangle imageRectangle = new Rectangle((int)(this.DisplayRectangle.Right - this._posOffset - this._image.Width - base.Padding.Right), (int)((this.DisplayRectangle.Top + this.DisplayRectangle.Height) - this._posOffset - this._image.Height - base.Padding.Bottom), this._image.Width, this._image.Height);

                            if (base.Enabled)
                            {
                                if (this.Alpha != 255)
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel, imageAttributes);

                                }
                                else
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel);

                                }

                            }
                            else
                            {
                                ControlPaint.DrawImageDisabled(e.Graphics, this._image, (int)(this.DisplayRectangle.Right - this._posOffset - this._image.Width - base.Padding.Right), (int)((this.DisplayRectangle.Top + this.DisplayRectangle.Height) - this._posOffset - this._image.Height - base.Padding.Bottom), Color.Transparent);

                            }

                            this.InternalRight += (this._posOffset + this.Image.Width);

                            bounds = new RectangleF(this.InternalLeft, topPosition, (this.DisplayRectangle.Width - ((this.InternalLeft - this.DisplayRectangle.Left) + this.InternalRight)), (this.DisplayRectangle.Height - (this.InternalTop + this.InternalBottom)));

                        }
                        else if (this._imageAlign == ContentAlignment.TopCenter)
                        {
                            Rectangle imageRectangle = new Rectangle((int)(((this.DisplayRectangle.Width / 2.0f) + this.DisplayRectangle.Left) - (this._image.Width / 2.0f)), (int)(this.DisplayRectangle.Top + this._posOffset + base.Padding.Top), this._image.Width, this._image.Height);

                            if (base.Enabled)
                            {
                                if (this.Alpha != 255)
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel, imageAttributes);

                                }
                                else
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel);

                                }

                            }
                            else
                            {
                                ControlPaint.DrawImageDisabled(e.Graphics, this._image, (int)(((this.DisplayRectangle.Width / 2.0f) + this.DisplayRectangle.Left) - (this._image.Width / 2.0f)), (int)(this.DisplayRectangle.Top + this._posOffset + base.Padding.Top), Color.Transparent);

                            }

                            bounds = new RectangleF(this.InternalLeft, topPosition, (this.DisplayRectangle.Width - ((this.InternalLeft - this.DisplayRectangle.Left) + this.InternalRight)), (this.DisplayRectangle.Height - (this.InternalTop + this.InternalBottom)));

                        }
                        else if (this._imageAlign == ContentAlignment.BottomCenter)
                        {
                            Rectangle imageRectangle = new Rectangle((int)(((this.DisplayRectangle.Width / 2.0f) + this.DisplayRectangle.Left) - (this._image.Width / 2.0f)), (int)((this.DisplayRectangle.Top + this.DisplayRectangle.Height) - this._posOffset - this._image.Height - base.Padding.Bottom), this._image.Width, this._image.Height);

                            if (base.Enabled)
                            {
                                if (this.Alpha != 255)
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel, imageAttributes);

                                }
                                else
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel);

                                }

                            }
                            else
                            {
                                ControlPaint.DrawImageDisabled(e.Graphics, this._image, (int)(((this.DisplayRectangle.Width / 2.0f) + this.DisplayRectangle.Left) - (this._image.Width / 2.0f)), (int)((this.DisplayRectangle.Top + this.DisplayRectangle.Height) - this._posOffset - this._image.Height - base.Padding.Bottom), Color.Transparent);

                            }

                            bounds = new RectangleF(this.InternalLeft, topPosition, (this.DisplayRectangle.Width - ((this.InternalLeft - this.DisplayRectangle.Left) + this.InternalRight)), (this.DisplayRectangle.Height - (this.InternalTop + this.InternalBottom)));

                        }
                        else //centered
                        {
                            Rectangle imageRectangle = new Rectangle((int)(((this.DisplayRectangle.Width / 2.0f) + this.DisplayRectangle.Left) - (this._image.Width / 2.0f)), (int)(((this.DisplayRectangle.Height / 2.0f) + this.DisplayRectangle.Top) - (this._image.Height / 2.0f)), this._image.Width, this._image.Height);

                            if (base.Enabled)
                            {
                                if (this.Alpha != 255)
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel, imageAttributes);

                                }
                                else
                                {
                                    e.Graphics.DrawImage(this._image, imageRectangle, 0, 0, this._image.Width, this._image.Height, GraphicsUnit.Pixel);

                                }

                            }
                            else
                            {
                                ControlPaint.DrawImageDisabled(e.Graphics, this._image, (int)(((this.DisplayRectangle.Width / 2.0f) + this.DisplayRectangle.Left) - (this._image.Width / 2.0f)), (int)(((this.DisplayRectangle.Height / 2.0f) + this.DisplayRectangle.Top) - (this.Image.Height / 2.0f)), Color.Transparent);

                            }

                            bounds = new RectangleF(this.InternalLeft, topPosition, (this.DisplayRectangle.Width - ((this.InternalLeft - this.DisplayRectangle.Left) + this.InternalRight)), (this.DisplayRectangle.Height - (this.InternalTop + this.InternalBottom)));

                        }

                    }
                    else
                    {

                        bounds = new RectangleF(this.InternalLeft, topPosition, (this.DisplayRectangle.Width - ((this.InternalLeft - this.DisplayRectangle.Left) + this.InternalRight)), (this.DisplayRectangle.Height - (this.InternalTop + this.InternalBottom)));

                    }

                }
                catch
                {
                    throw;

                }
                finally
                {
                    imageAttributes.Dispose();

                }

                if (!string.IsNullOrEmpty(this._text))
                {
                    if (!bounds.IsEmpty)
                    {
                        if (this._useCompatibleTextRendering)
                        {
                            if (adjustedTextAlignment == ContentAlignment.TopLeft)
                            {                                
                                this._textFormat.Alignment = StringAlignment.Near;
                                this._textFormat.LineAlignment = StringAlignment.Near;

                            }
                            else if (adjustedTextAlignment == ContentAlignment.MiddleLeft)
                            {
                                this._textFormat.Alignment = StringAlignment.Near;
                                this._textFormat.LineAlignment = StringAlignment.Center;

                            }
                            else if (adjustedTextAlignment == ContentAlignment.BottomLeft)
                            {
                                this._textFormat.Alignment = StringAlignment.Near;
                                this._textFormat.LineAlignment = StringAlignment.Far;

                            }
                            else if (adjustedTextAlignment == ContentAlignment.TopCenter)
                            {
                                this._textFormat.Alignment = StringAlignment.Center;
                                this._textFormat.LineAlignment = StringAlignment.Near;

                            }
                            else if (adjustedTextAlignment == ContentAlignment.MiddleCenter)
                            {
                                this._textFormat.Alignment = StringAlignment.Center;
                                this._textFormat.LineAlignment = StringAlignment.Center;

                            }
                            else if (adjustedTextAlignment == ContentAlignment.BottomCenter)
                            {
                                this._textFormat.Alignment = StringAlignment.Center;
                                this._textFormat.LineAlignment = StringAlignment.Far;

                            }
                            else if (adjustedTextAlignment == ContentAlignment.TopRight)
                            {
                                this._textFormat.Alignment = StringAlignment.Far;
                                this._textFormat.LineAlignment = StringAlignment.Near;

                            }
                            else if (adjustedTextAlignment == ContentAlignment.MiddleRight)
                            {
                                this._textFormat.Alignment = StringAlignment.Far;
                                this._textFormat.LineAlignment = StringAlignment.Center;

                            }
                            else if (adjustedTextAlignment == ContentAlignment.BottomRight)
                            {
                                this._textFormat.Alignment = StringAlignment.Far;
                                this._textFormat.LineAlignment = StringAlignment.Far;

                            }

                            e.Graphics.DrawString(this._text, this._font, this._foreBrush, bounds, this._textFormat);

                        }
                        else
                        {
                            Rectangle rectangle = new Rectangle((int)bounds.X, (int)bounds.Y, (int)bounds.Width, (int)bounds.Height);

                            TextFormatFlags textFormatFlags;

                            if (adjustedTextAlignment == ContentAlignment.TopLeft)
                            {
                                if (this._rightToLeft)
                                {
                                    textFormatFlags = TextFormatFlags.Left | TextFormatFlags.Top | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.RightToLeft;

                                }
                                else
                                {
                                    textFormatFlags = TextFormatFlags.Left | TextFormatFlags.Top | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding;

                                }

                            }
                            else if (adjustedTextAlignment == ContentAlignment.MiddleLeft)
                            {
                                if (this._rightToLeft)
                                {
                                    textFormatFlags = TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.RightToLeft;

                                }
                                else
                                {
                                    textFormatFlags = TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding;

                                }

                            }
                            else if (adjustedTextAlignment == ContentAlignment.BottomLeft)
                            {
                                if (this._rightToLeft)
                                {
                                    textFormatFlags = TextFormatFlags.Left | TextFormatFlags.Bottom | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.RightToLeft;

                                }
                                else
                                {
                                    textFormatFlags = TextFormatFlags.Left | TextFormatFlags.Bottom | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding;

                                }

                            }
                            else if (adjustedTextAlignment == ContentAlignment.TopCenter)
                            {
                                if (this._rightToLeft)
                                {
                                    textFormatFlags = TextFormatFlags.HorizontalCenter | TextFormatFlags.Top | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.RightToLeft;

                                }
                                else
                                {
                                    textFormatFlags = TextFormatFlags.HorizontalCenter | TextFormatFlags.Top | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding;

                                }

                            }
                            else if (adjustedTextAlignment == ContentAlignment.MiddleCenter)
                            {
                                if (this._rightToLeft)
                                {
                                    textFormatFlags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.RightToLeft;

                                }
                                else
                                {
                                    textFormatFlags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding;

                                }

                            }
                            else if (adjustedTextAlignment == ContentAlignment.BottomCenter)
                            {
                                if (this._rightToLeft)
                                {
                                    textFormatFlags = TextFormatFlags.HorizontalCenter | TextFormatFlags.Bottom | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.RightToLeft;

                                }
                                else
                                {
                                    textFormatFlags = TextFormatFlags.HorizontalCenter | TextFormatFlags.Bottom | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding;

                                }

                            }
                            else if (adjustedTextAlignment == ContentAlignment.TopRight)
                            {
                                if (this._rightToLeft)
                                {
                                    textFormatFlags = TextFormatFlags.Right | TextFormatFlags.Top | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.RightToLeft;

                                }
                                else
                                {
                                    textFormatFlags = TextFormatFlags.Right | TextFormatFlags.Top | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding;

                                }

                            }
                            else if (adjustedTextAlignment == ContentAlignment.MiddleRight)
                            {
                                if (this._rightToLeft)
                                {
                                    textFormatFlags = TextFormatFlags.Right | TextFormatFlags.VerticalCenter | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.RightToLeft;

                                }
                                else
                                {
                                    textFormatFlags = TextFormatFlags.Right | TextFormatFlags.VerticalCenter | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding;

                                }

                            }
                            else //bottom right
                            {
                                if (this._rightToLeft)
                                {
                                    textFormatFlags = TextFormatFlags.Right | TextFormatFlags.Bottom | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding | TextFormatFlags.RightToLeft;

                                }
                                else
                                {
                                    textFormatFlags = TextFormatFlags.Right | TextFormatFlags.Bottom | TextFormatFlags.WordEllipsis | TextFormatFlags.GlyphOverhangPadding;

                                }

                            }

                            string passedText = this._text;

                            if (this._hidePrefix)
                            {
                                textFormatFlags |= TextFormatFlags.HidePrefix;
                                if (passedText.Contains("&")) passedText = passedText.Replace("&", "&&");

                            }

                            TextRenderer.DrawText(e.Graphics, passedText, this._font, rectangle, this._foreBrush.Color, textFormatFlags);

                        }

                    }

                }

            }

        }

        private ContentAlignment GetAdjustedTextAlignment()
        {
            ContentAlignment adjustedAlignment;

            if (!this._rightToLeft)
            {
                adjustedAlignment = this._textAlign;

            }
            else
            {
                if (this._textAlign == ContentAlignment.BottomRight)
                {
                    adjustedAlignment = ContentAlignment.BottomLeft;

                }
                else if (this._textAlign == ContentAlignment.MiddleRight)
                {
                    adjustedAlignment = ContentAlignment.MiddleLeft;

                }
                else if (this._textAlign == ContentAlignment.TopRight)
                {
                    adjustedAlignment = ContentAlignment.TopLeft;

                }
                else if (this._textAlign == ContentAlignment.BottomLeft)
                {
                    adjustedAlignment = ContentAlignment.BottomRight;

                }
                else if (this._textAlign == ContentAlignment.MiddleLeft)
                {
                    adjustedAlignment = ContentAlignment.MiddleRight;

                }
                else if (this._textAlign == ContentAlignment.TopLeft)
                {
                    adjustedAlignment = ContentAlignment.TopRight;

                }
                else
                {
                    adjustedAlignment = this._textAlign;

                }

            }

            return adjustedAlignment;

        }

        /// <summary>
        /// Gets the size needed to fit the current content.
        /// </summary>
        /// <returns>The size.</returns>
        public Size GetAutoSize()
        {
            Size size = TextRenderer.MeasureText(this._text, this._font);

            size.Width += (base.Padding.Left + this._posOffset + this._autoSizeBuffer);
            size.Width += (base.Padding.Right + this.Border.Right + this._autoSizeBuffer);

            if ((this._image != null) && (this._image.PixelFormat != System.Drawing.Imaging.PixelFormat.Undefined) && (this._image.Height > 0))
            {
                if (this._imageAlign != ContentAlignment.BottomCenter && this._imageAlign != ContentAlignment.MiddleCenter && this._imageAlign != ContentAlignment.TopCenter)
                {
                    size.Width += this._image.Width;
                    size.Width += 4;

                }

                if (this._image.Height > size.Height)
                {
                    size.Height = this._image.Height;

                }

            }

            size.Height += (base.Padding.Top + this.Border.Top + this._autoSizeBuffer);
            size.Height += (base.Padding.Bottom + this.Border.Bottom + this._autoSizeBuffer);

            return size;

        }

        /// <summary>
        /// Releases all resources used.
        /// </summary>
        /// <param name="disposing">true or false</param>
        protected override void Dispose(bool disposing)
        {
            try
            {
                if (!this._disposed)
                {
                    if (disposing)
                    {
                        if (this._image != null) this._image = null;
                        if (this._foreBrush != null) this._foreBrush.Dispose();
                        if (this._textFormat != null) this._textFormat.Dispose();

                    }

                }

                this._disposed = true;

            }
            catch
            {
                throw;

            }
            finally
            {
                base.Dispose(disposing);

            }

        }

        /// <summary>
        /// Raises the ForeColorChanged event. 
        /// </summary>
        /// <param name="e">An System.EventArgs that contains the event data.</param>
        protected virtual void OnForeColorChanged(System.EventArgs e)
        {
            if (this.ForeColorChanged != null)
            {
                this.ForeColorChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that control image alignment has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnImageAlignChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnImageAlignChanged(EventArgs e)
        {
            if (this.ImageAlignChanged != null)
            {
                this.ImageAlignChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that control image has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnImageChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnImageChanged(EventArgs e)
        {
            if (this.ImageChanged != null)
            {
                this.ImageChanged(this, e);

            }

        }

        /// <summary>
        /// Fires the event indicating that control text alignment has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnTextAlignChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnTextAlignChanged(EventArgs e)
        {
            if (this.TextAlignChanged != null)
            {
                this.TextAlignChanged(this, e);

            }

        }

        /// <summary>
        /// Raises the TextChanged event.
        /// </summary>
        /// <param name="e">An System.EventArgs that contains the event data.</param>
        protected virtual void OnTextChanged(System.EventArgs e)
        {
            if (this.TextChanged != null)
            {
                this.TextChanged(this, e);

            }


        }

    }

}
